require 'webapp_exceptions'
class WebappController < ApplicationController
  helper :all # include all helpers, all the time
  include ApplicationHelper
  include WebappHelper
  
  before_filter :detect_auto_login_cookie, :set_session_from_fb, :set_current_user
  #Define the base layout. For not hard coded
  layout :determine_layout
  
  
  unless ActionController::Base.consider_all_requests_local
    rescue_from Exception do |exception|
      logger.error(exception)
      respond_to do |format|
        format.html { render :template => "/error/500", :status => 500}
        format.fbml { render :template => "/error/500", :status => 500}
        format.json { render :json => {:error=>"Error 500 - Internal Server Error"} }
        format.fbjs { render :json => {:error=>"Error 500 - Internal Server Error"} }
      end
      
    end
    rescue_from ActiveRecord::RecordNotFound do |exception|
      logger.error(exception)
      respond_to do |format|
        format.html { flash_error(:record_not_found); redirect_to root_url}
        format.fbml { flash_error(:record_not_found); redirect_to root_url}
        format.json { render :json => {:error=>"Error 404: Not found"} }
        format.fbjs { render :json => {:error=>"Error 404: Not found"} }
      end
      
      
    end
  end
  rescue_from Webapp::BadParametersError do |exception|
      logger.error(exception)
      respond_to do |format|
        format.html { render :template => "/error/400", :status => 400}
        format.fbml { render :template => "/error/400", :status => 400}
        format.json { render :json => {:error=>"Error 400 - Bad Request"} }
        format.fbjs { render :json => {:error=>"Error 400 - Bad Request"} }
      end

  end
  rescue_from Webapp::NotAuthenticated,Webapp::WrongAuthenticatedUser do |exception|
      logger.error(exception)
      respond_to do |format|
        #format.html { render :template => "/error/401", :status => 401}
        format.html { flash_error(:authentication_needed);redirect_to new_session_url()}
        
        #format.fbml { render :template => "/error/401", :status => 401}
        format.fbml { redirect_to register_fb_user_url() }
        format.json { render :json => {:error=>"Error 401 - Not Authorized"} }
        format.fbjs { render :json => {:error=>"Error 401 - Not Authorized"} }
      end

    
  end
  
  
  protected
  #determine the layout to use
  def determine_layout
    #"earthlingtwo/earthlingtwo"
    #"#{template_name}/#{template_name}"
    #todo: If a more advanced template system is needed
    "default"
    
  end
  
  #Convenience method to add an error to the flash
  def flash_error(message_key,*strs)
    flash[:error] = sprintf(I18n.t(message_key),*strs)
  end
  
  #Convenience method to add and note to flash
  def flash_notice(message_key, *strs)
    flash[:notice] = sprintf(I18n.t(message_key),*strs)
  end
  
  #
  #Redirect a user to a new URL and set a Error message
  def redirect_to_last_page_with_error(message_key, *strs)
    new_url = session[:return_to] || root_url
    
    session[:return_to] = nil
    
    flash_error(message_key, *strs)
    redirect_to new_url
  end
  
  
  ###########################
  # Redirects user to last page or to HOME if none was set
  #########################
  def redirect_to_last_page

    new_url = session[:return_to] || root_url
    session[:return_to] = nil
    redirect_to new_url
  end
  
  #If a User session does not exists but a cookie to login exists, then try to do an auto login
  def detect_auto_login_cookie    
    if session[:user_session].nil? and cookies[WebappConstants::AUTO_LOGIN_COOKIE_NAME]
      session[:return_to] = request.request_uri
      logger.info("Doing auto login")
      do_auto_login
      #redirect_to :controller=>:session, :action=>do_auto_login
    end
  end
  
  def create_session(user, show_message=true)
    #fb_uid = facebook_user.uid if facebook_user
    user_session = UserSession.new(user)
    session[:user_session] = user_session
    flash_notice(:login_successfull) if show_message
    
  end
  def set_current_user
    if user_session
      @current_user = @current_user || User.find(user_session.user_id)
    else
      @current_user = nil
    end
  rescue ActiveRecord::RecordNotFound
    @current_user = nil
    
  end
  #
  # Detect a facebook session and if exists, try to find the user. 
  # If user is found, then do auto login
  #----------------------------------------------------------------------------------
  def set_session_from_fb
    set_facebook_session
    logger.debug "Doing auto login for registered facebook users"
    #check if any session exists
    if not has_session?
      #check if exists any facebook_session     
      if facebook_session_secured?
        user = User.find_by_fb_uid(facebook_user.uid)
        #try to get the user from DB
        create_session(user, false) if user  
      end
      #check if application is installed
      #user = User.find_by_fb_uid(facebook_user.uid)
    elsif (facebook_session_secured?)
      user = User.find(user_session.user_id)
      if (user.fb_uid and user.fb_uid!=facebook_user.uid)
        session[:facebook_session] = nil
      end
      
    end
    
 
 
  end
  
  
  def do_auto_login
    user_id = get_user_id_from_auto_login_cookie_value(cookies[WebappConstants::AUTO_LOGIN_COOKIE_NAME])
    key = get_key_from_auto_login_cookie_value(cookies[WebappConstants::AUTO_LOGIN_COOKIE_NAME]) 
    user = User.find(user_id)
    if  user 
      
      persistent_session = PersistentSession.find_by_user_id(user_id)
      if persistent_session 
        
        
        if persistent_session.key == key
          
          #login the user
          user_session = UserSession.new(user)    
          session[:user_session] = user_session
          #create new persisten session
          create_persistent_session(user.id)
          #PersistentSession.create_session(user_id) 
          #Add cookie
          #cookies[WebappConstants::AUTO_LOGIN_COOKIE_NAME] = 
          redirect_to_last_page
          #redirect_to session[:return_to] || root_url
          
          #session[:return_to] = nil
        else
          remove_persistent_session(user_id)
          redirect_to root_url
        end
      else
        redirect_to root_url
      end    
    end
  rescue ActiveRecord::RecordNotFound
    #clear sessions and cookies
    clear_user_session
    remove_persistent_session
  end 
  
  def remove_persistent_session(user_id=nil)
    cookies.delete WebappConstants::AUTO_LOGIN_COOKIE_NAME
    PersistentSession.clear_session(user_id) if user_id
  end
  
  def clear_user_session(user_id=nil)
    session[:user_session] = nil
    remove_persistent_session(user_id) if user_id
    session[:facebook_session] = nil
    reset_session
  end
  
  def create_persistent_session(user_id)
    cookies[WebappConstants::AUTO_LOGIN_COOKIE_NAME]= {:value=>create_auto_login_cookie_value(PersistentSession.create_session(user_id)), 
      :expires=>WebappConstants::MAX_AUTO_LOGIN_COOKIE_AGE.days.from_now}
  end
  
  def create_auto_login_cookie_value(persistent_session)
    "#{persistent_session.user_id}:#{persistent_session.key}"
  end
  def get_user_id_from_auto_login_cookie_value(cookie_value)
    value = /\A\d+/i.match(cookie_value).to_s.to_i
  end
  
  def get_key_from_auto_login_cookie_value(cookie_value) 
    value = /[^\d:][\S]+/i.match(cookie_value).to_s
  end
  
  
end